/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package io.renren.modules.project.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.project.dao.PublishDao;
import io.renren.modules.project.entity.DatasourceEntity;
import io.renren.modules.project.entity.FrontendEntity;
import io.renren.modules.project.entity.ModuleEntity;
import io.renren.modules.project.entity.PublishEntity;
import io.renren.modules.project.service.DatasourceService;
import io.renren.modules.project.service.FrontendService;
import io.renren.modules.project.service.ModuleService;
import io.renren.modules.project.service.PublishService;
import io.renren.modules.systemconfig.dao.SysConfigServerDao;
import io.renren.modules.systemconfig.entity.ProjectBaseEntity;
import io.renren.modules.systemconfig.entity.SystemConfigServersEntity;
import io.renren.ssh.AsyncCmdCallBack;
import io.renren.ssh.FileAttri;
import io.renren.ssh.SFTPClient;
import io.renren.ssh.SSHClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Vector;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("publishService")
public class PublishServiceImpl extends ServiceImpl<PublishDao, PublishEntity> implements PublishService {
	@Autowired
	private FrontendService frontendService;
	@Autowired
	private ModuleService moduleService;

	@Autowired
	private SysConfigServerDao serverMapper;


	@Autowired
	private DatasourceService datasourceService;

	@Value("${spring.web.upload-path}")
	private String basepath;


	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String type = (String)params.get("type");
		String objectId = (String)params.get("objectId");
		if("vue".equals(type)){
			IPage<PublishEntity> page = this.page(
					new Query<PublishEntity>().getPage(params),
					new QueryWrapper<PublishEntity>().eq(StringUtils.isNotBlank(type),"type", type).eq(StringUtils.isNotBlank(objectId),"object_id", objectId).orderByDesc("create_time")
			);
			return new PageUtils(page);
		}else{
			IPage<PublishEntity> page = this.page(
					new Query<PublishEntity>().getPage(params),
					new QueryWrapper<PublishEntity>().ne(StringUtils.isNotBlank(type),"type", "vue").eq(StringUtils.isNotBlank(objectId),"object_id", objectId).orderByDesc("create_time")
			);
			return new PageUtils(page);
		}



	}


	@Override
	public PublishEntity queryByKey(String key) {
		return baseMapper.queryByKey(key);
	}

	@Override
	@Transactional
	public void saveEntity(PublishEntity entity) {
		this.baseMapper.insert(entity);
	}

	@Override
	@Transactional
	public void update(PublishEntity user) {
		this.updateById(user);
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}

	@Override
	public void publishVersionToRuntime(Long id) {
		PublishEntity entity = this.getById(id);
		if(entity==null){
			throw new RRException("本版不存在！");
		}
		String destFileName=basepath + File.separator+"file" + File.separator + entity.getFileSaveName();
		if("vue".equals(entity.getType())){
			long frontId = entity.getObjectId();
			FrontendEntity fe=frontendService.getAllInfoById(frontId);
			if(fe!=null&&fe.getServer()!=null){
				try{
					SSHClient ssh = new SSHClient(fe.getServer());
					StringBuffer sb=ssh.exec("rm -rf  "+fe.getDeployPath()+"/*");
					System.out.println(sb);

					SFTPClient sftp = new SFTPClient(fe.getServer());
					sftp.upload( fe.getDeployPath(),destFileName,entity.getFileUploadName());
					sftp.close();


					sb=ssh.exec("unzip -n  -d "+fe.getDeployPath()+ " "+fe.getDeployPath()+"/"+entity.getFileUploadName());
					System.out.println(sb);

					sb=ssh.exec("mv "+fe.getDeployPath()+"/dist" + " "+fe.getDeployPath() );
					System.out.println(sb);

					fe.setStatus(2);
					frontendService.update(fe);

					ssh.close();

				}catch (Exception e){
					e.printStackTrace();
				}
			}

		}else{
				long moduleId = entity.getObjectId();
				ModuleEntity me=moduleService.getById(moduleId);
				if(me!=null&&me.getServerId()!=null){
					try{
						SFTPClient sftp = new SFTPClient(serverMapper.selectById(me.getServerId()));
						sftp.upload( me.getDeployPath(),destFileName,entity.getFileUploadName());
						sftp.close();

						me.setStatus(2);
						moduleService.update(me);

					}catch (Exception e){
						e.printStackTrace();
					}
				}
		}


	}

	@Override
	public void restartFront(Long id) {
			FrontendEntity fe=frontendService.getAllInfoById(id);
			if(fe!=null&&fe.getServer()!=null){
				try{
					SSHClient ssh = new SSHClient(fe.getServer());
					System.out.println(fe.getNginxBasePath()+"/sbin/nginx -s reload");
					StringBuffer sb=ssh.exec(fe.getNginxBasePath()+"/sbin/nginx -s reload");
					System.out.println(sb);
					ssh.close();
				}catch (Exception e){
					e.printStackTrace();
				}
			}
	}

	@Override
	public void restartSources(Long id) {
		DatasourceEntity de=datasourceService.getAllInfo(id);
		if(de!=null&&de.getServer()!=null){
			try{
				SSHClient ssh = new SSHClient(de.getServer());
				System.out.println(de.getDatasourceType()+"    "+de.getDeployPath()+"  "+de.getConfigPath());
				if("mysql".equals(de.getDatasourceType())){
					StringBuffer sb=ssh.exec("service mysql restart");
					System.out.println(sb);
				}else if("redis".equals(de.getDatasourceType())){
					StringBuffer sb=ssh.exec("service redis restart");
					System.out.println(sb);
				}else if("mongodb".equals(de.getDatasourceType())){
					StringBuffer sb=ssh.exec("service mongodb restart");
					System.out.println(sb);
				}


				ssh.close();
			}catch (Exception e){
				e.printStackTrace();
			}
		}
	}

	@Override
	public void restartBackend(Long id) {
		ModuleEntity me=moduleService.getById(id);
		if("springboot".equals(me.getModuleType())||"gateway".equals(me.getModuleType())||"eureka".equals(me.getModuleType())){
			if(me!=null&&me.getDeployPath()!=null){
				try{
					SystemConfigServersEntity scs = serverMapper.selectById(me.getServerId());
					SFTPClient sftp = new SFTPClient(scs);
					SSHClient ssh = new SSHClient(scs);
					StringBuffer sb= null;
					if(!sftp.isExist(me.getDeployPath()+"/stop-"+me.getName()+".sh")){
						String content="PID=$(ps -ef | grep "+me.getNameJar()+" | grep -v grep | awk '{ print $2 }')\n" +
								"if [ -z \"$PID\" ]\n" +
								"then\n" +
								"echo \"not start\" \n"+
								"else\n" +
								"echo kill -9 $PID\n" +
								"kill -9 $PID\n" +
								"echo \"stop\" \n"+
								"fi\n" ;
						sftp.uploadContent(me.getDeployPath(),"stop-"+me.getName()+".sh",content);
						sftp.close();


						ssh.exec("chmod +x "+me.getDeployPath()+"/stop-"+me.getName()+".sh");


					}
					System.out.println(ssh.exec(me.getDeployPath()+"/stop-"+me.getName()+"\n"));
					System.out.println(ssh.exec("source /etc/profile && nohup java -jar "+me.getDeployPath()+"/"+me.getNameJar()+" & \n"));

//					Thread.sleep(5000);
//					System.out.println(sb);
					ssh.close();


				}catch (Exception e){
					e.printStackTrace();
				}
			}else{
				throw new RRException("没找到对应模块!");
			}
		}
	}

	@Override
	public void unzipFile(Long id, String path) throws Exception{
		SystemConfigServersEntity scs = serverMapper.selectById(id);
		SSHClient ssh = new SSHClient(scs);
		System.out.println("unzip -n  -d "+path.substring(0,path.lastIndexOf("/"))+ " "+path);
		StringBuffer sb=ssh.exec("unzip -n  -d "+path.substring(0,path.lastIndexOf("/"))+ " "+path);
		System.out.println(sb);
	}

	@Override
	public void delSFTPFiles(SystemConfigServersEntity scs, String path)  throws Exception{
		System.out.println(path);
		SFTPClient sftp = new SFTPClient(scs);


		List<FileAttri> files = sftp.ls(path,false,null);
		if(files==null){
			sftp.rmFile(path);
		}else if(files.isEmpty()){
			sftp.rmDir(path);
		}else{
			for(FileAttri fa:files){
				System.out.println(JSONObject.toJSONString(fa));
				if(fa.isDir()){
					delSFTPFiles(scs,fa.getPath());
				}else{
					sftp.rmFile(fa.getPath());
				}

			}
			sftp.rmDir(path);
		}

		sftp.close();
	}
}